﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Types;
using System.Text.RegularExpressions;

namespace NAntExt.Tasks
{
    /// <summary>
    /// A regular expression task to do group matching and continue even 
    /// when it doesn't match the pattern. It will concat the group matches
    /// together with a comma if multiple are found.
    /// </summary>
    [TaskName("regex-ext")]
    public class RegexExtTask : Task
    {

        /// <summary>
        /// The input for the regular expression.
        /// </summary>
        [TaskAttribute("input", Required = true)]
        [StringValidator(AllowEmpty = true)]
        public string Input { get; set; }

        /// <summary>
        /// The pattern to match the input
        /// </summary>
        [TaskAttribute("pattern", Required = true)]
        [StringValidator(AllowEmpty = false)]
        public string Pattern { get; set; }

        /// <summary>
        /// The delimineter to use to concat any multiple
        /// group matches together. Default is a comma.
        /// </summary>
        [TaskAttribute("delim", Required = false)]
        [StringValidator(AllowEmpty = false)]
        public string Delimineter { get; set; }

        private RegexOptions _options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace;

        /// <summary>
        /// The pattern to match the input
        /// </summary>
        [TaskAttribute("options", Required = false)]
        [StringValidator(AllowEmpty = false)]
        public string Options
        {
            get
            {
                return _options.ToString();
            }
            set
            {
                _options = (RegexOptions)Enum.Parse(typeof(RegexOptions), value);
            }
        }


        /// <summary>
        /// Entry point for the task.
        /// </summary>
        protected override void ExecuteTask()
        {
            try
            {
                var regex = new Regex(this.Pattern, _options);
                Match match = regex.Match(this.Input);
                foreach (var groupName in regex.GetGroupNames())
                {
                    string groupProperty = string.Empty;
                    Group group = match.Groups[groupName];
                    if (match.Success && group != null && group.Success)
                    {
                        foreach (Capture capture in group.Captures)
                        {
                            if (groupProperty != string.Empty)
                                groupProperty += (string.IsNullOrEmpty(Delimineter)) ? "," : Delimineter;

                            groupProperty += capture.Value;
                        }
                    }
                    this.Properties[groupName] = groupProperty;
                }
            }
            catch (Exception ex)
            {
                this.ThrowOrLog(this.Location, ex);
            }
        }

    }
}
